// DecisionStack.java
package org.zjx.core;

import lombok.Data;
import org.zjx.core.state.StateAccessor;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Optional;

/**
 * 决策调用栈 - 跟踪决策节点的执行路径
 *
 * 这个类维护了一个栈结构，记录当前正在执行的决策节点及其对应的状态快照，
 * 用于调试和可能的回溯操作。
 */
public class DecisionStack {
    // 使用ArrayDeque作为底层实现的栈
    private final Deque<Frame> stack = new ArrayDeque<>();

    /**
     * 栈帧结构 - 封装决策节点和对应的状态快照
     */
    @Data
    public static class Frame {
        // 当前正在执行的决策节点
        private final DecisionNode currentNode;
        // 执行该节点时的状态
        private final StateAccessor stateAccessor;

        /**
         * 构造函数
         *
         * @param currentNode 当前决策节点
         * @param stateAccessor 状态
         */
        public Frame(DecisionNode currentNode,StateAccessor stateAccessor) {
            this.currentNode = currentNode;
            this.stateAccessor = stateAccessor;
        }
    }

    /**
     * 压入栈帧
     *
     * @param node 要压入栈的决策节点
     * @param stateAccessor 对应的状态
     */
    public void push(DecisionNode node,  StateAccessor stateAccessor) {
        stack.push(new Frame(node, stateAccessor));
    }

    /**
     * 弹出栈帧
     *
     * @return 被弹出的栈帧
     */
    public Frame pop() {
        return stack.pop();
    }

    /**
     * 查看栈顶帧(不移除)
     *
     * @return 包含栈顶帧的Optional，如果栈为空则为空
     */
    public Optional<Frame> peek() {
        return Optional.ofNullable(stack.peek());
    }

    /**
     * 判断栈是否为空
     *
     * @return 如果栈为空返回true，否则false
     */
    public boolean isEmpty() {
        return stack.isEmpty();
    }
}